module fn.adt.graph.search.Pattern


open System.Collections.Generic

open QuickGraph

open fn.pattern.Collection

open fn.adt.Tree




type MatchObject<'V,'Ky,'Va when 'Va : equality> =
    { edges : HashSet<IEdge<'V>>
      matched : IDictionary<'Ky, 'Va> }

    static member ( ++ ) (a : MatchObject<_,_,_>, b : MatchObject<_,_,_>) =
        let iter (m : IDictionary<_,_>) = seq { for KeyValue(k,v) in m -> (k,v) }
        { edges=HashSet.union a.edges b.edges
          matched=Map.ofSeq (Seq.concat [|iter a.matched; iter b.matched|])}

    member this.conflicts (other : MatchObject<_,_,_>) =
        (HashSet.intersection this.edges other.edges).Count > 0 ||
            Seq.exists (fun (KeyValue(k,v)) -> other.matched.ContainsKey(k) && other.matched.[k] <> v) this.matched

    override this.ToString() =
        let edges = System.String.Join("; ", this.edges)
        let matched = 
            System.String.Join("\n", 
                seq {
                    for KeyValue(k,v) in this.matched -> sprintf "%O -> %O" k v
                })
        edges + "\n" + matched
